package cn.sixos.dao;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class HibernateDao {
	private SessionFactory sessionFactory;

	/**
	 * 获得Hibernate的Session对象
	 * 
	 * @return session
	 */
	public Session getSession() {
		return sessionFactory.getCurrentSession();
	}

	/**
	 * 保存实体对象
	 * 
	 * @param entity
	 *            实体对象
	 */
	public <T> void save(T entity) {
		getSession().save(entity);
	}

	/**
	 * 更新实体对象
	 * 
	 * @param entity
	 *            实体对象
	 */
	public <T> void update(T entity) {
		getSession().update(entity);
	}

	/**
	 * 删除实体对象
	 * 
	 * @param entity
	 *            实体对象
	 */
	public <T> void delete(T entity) {
		getSession().delete(entity);
	}

	/**
	 * 按类型和ID删除实体对象
	 * 
	 * @param clazz
	 *            实体对象类型
	 * @param id
	 *            ID
	 */
	public <T> void delete(Class<T> clazz, long id) {
		// 通过实体类型的class名称和id生成HQL
		String hql = "DELETE FROM " + clazz.getName() + " WHERE id=:id";
		// 创建Hibernate的查询对象
		Query query = getSession().createQuery(hql);
		// 设置参数
		query.setLong("id", id);
		// 执行操作
		query.executeUpdate();
	}

	/**
	 * 按类型和ID查询实体对象
	 * 
	 * @param clazz
	 *            实体对象类型
	 * @param id
	 *            ID
	 * @return 实体对象
	 */
	@SuppressWarnings("unchecked")
	public <T> T findById(Class<T> clazz, Serializable id) {
		return (T) getSession().get(clazz, id);
	}

	/**
	 * 按HQL查询数据
	 * 
	 * @param hql
	 *            HQL
	 * @return 数据集合列表
	 */
	@SuppressWarnings("unchecked")
	public <T> List<T> find(String hql) {
		// 通过HQL建立查询对象
		Query query = getSession().createQuery(hql);
		// 执行查询
		return query.list();
	}

	/**
	 * 查询符合条件的数据总量
	 * 
	 * @param hql
	 *            HQL
	 * @param params
	 *            参数MAP
	 * @return 数据集合列表
	 */
	public long count(String hql, Map<String, Object> params) {
		// 调用下边的findUniqueObject方法来得到符合条件的数据总量
		return findUniqueObject(hql, params);
	}

	/**
	 * 分布查询符合条件的数据
	 * 
	 * @param hql
	 *            HQL
	 * @param params
	 *            参数MAP
	 * @param firstResult
	 *            分页的首行位置
	 * @param pageSize
	 *            每页数据数量
	 * @return 数据集合列表
	 */
	@SuppressWarnings("unchecked")
	public <T> List<T> findBy(String hql, Map<String, Object> params,
			int firstResult, int pageSize) {
		// 通过HQL建立查询对象
		Query query = getSession().createQuery(hql);
		// 设置参数到查询对象中去
		for (Entry<String, Object> param : params.entrySet()) {
			// 分析当前被遍历的参数类型，如果是Collection或数组类型，则用setParameterList方法设置参数；
			// 否则用setParameter方法设置参数
			if (param.getValue() instanceof Collection) {
				Collection<?> coll = (Collection<?>) param.getValue();
				query.setParameterList(param.getKey(), coll);
			} else if (param.getValue().getClass().isArray()) {
				Object[] arr = (Object[]) param.getValue();
				query.setParameterList(param.getKey(), arr);
			} else {
				query.setParameter(param.getKey(), param.getValue());
			}
		}

		// 设置分页信息
		query.setFirstResult(firstResult);
		query.setMaxResults(pageSize);
		// 查询数据
		return query.list();
	}

	/**
	 * 查询符合条件的数据
	 * 
	 * @param hql
	 *            HQL
	 * @param params
	 *            参数MAP
	 * @return 数据集合列表
	 */
	@SuppressWarnings("unchecked")
	public <T> List<T> findBy(String hql, Map<String, Object> params) {
		// 通过HQL建立查询对象
		Query query = getSession().createQuery(hql);
		// 设置参数到查询对象中去
		for (Entry<String, Object> param : params.entrySet()) {
			// 分析当前被遍历的参数类型，如果是Collection或数组类型，则用setParameterList方法设置参数；
			// 否则用setParameter方法设置参数
			if (param.getValue() instanceof Collection) {
				Collection<?> coll = (Collection<?>) param.getValue();
				query.setParameterList(param.getKey(), coll);
			} else if (param.getValue().getClass().isArray()) {
				Object[] arr = (Object[]) param.getValue();
				query.setParameterList(param.getKey(), arr);
			} else {
				query.setParameter(param.getKey(), param.getValue());
			}
		}
		// 查询数据
		return query.list();
	}

	/**
	 * 查询符合条件的唯一数据
	 * 
	 * @param hql
	 *            HQL
	 * @param params
	 *            参数MAP
	 * @return 数据结果
	 */
	@SuppressWarnings("unchecked")
	public <T> T findUniqueObject(String hql, Map<String, Object> params) {
		// 通过HQL建立查询对象
		Query query = getSession().createQuery(hql);
		// 设置参数到查询对象中去
		for (Entry<String, Object> param : params.entrySet()) {
			// 分析当前被遍历的参数类型，如果是Collection或数组类型，则用setParameterList方法设置参数；
			// 否则用setParameter方法设置参数
			if (param.getValue() instanceof Collection) {
				Collection<?> coll = (Collection<?>) param.getValue();
				query.setParameterList(param.getKey(), coll);
			} else if (param.getValue().getClass().isArray()) {
				Object[] arr = (Object[]) param.getValue();
				query.setParameterList(param.getKey(), arr);
			} else {
				query.setParameter(param.getKey(), param.getValue());
			}
		}
		// 查询数据
		return (T) query.uniqueResult();
	}

	/**
	 * 获得Hibernate的SessionFactory对象
	 * 
	 * @return SessionFactory对象
	 */
	public SessionFactory getSessionFactory() {
		return this.sessionFactory;
	}

	/**
	 * 设置Hibernate的SessionFactory对象
	 * 
	 * @param sessionFactory
	 *            SessionFactory对象
	 */
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

}
